﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;
using System.ServiceModel;
using System.Text;

namespace XYZShell.CSHelper.Web.WCF
{
    internal class ServiceRealProxy<T> : RealProxy
    {
        private string endpointName;
        public ServiceRealProxy(string endpointName)
            : base(typeof(T))
        {
            if (string.IsNullOrEmpty(endpointName))
            {
                throw new ArgumentNullException("endpointName");
            }
            this.endpointName = endpointName;
        }
        public override IMessage Invoke(IMessage msg)
        {
            T t = ChannelFactoryCreator.Create<T>(this.endpointName).CreateChannel();
            IMethodCallMessage methodCallMessage = (IMethodCallMessage)msg;
            IMethodReturnMessage result = null;
            object[] array = Array.CreateInstance(typeof(object), methodCallMessage.Args.Length) as object[];
            methodCallMessage.Args.CopyTo(array, 0);
            try
            {
                object ret = methodCallMessage.MethodBase.Invoke(t, array);
                result = new ReturnMessage(ret, array, array.Length, methodCallMessage.LogicalCallContext, methodCallMessage);
                (t as ICommunicationObject).Close();
            }
            catch (Exception ex)
            {
                if (ex.InnerException is CommunicationException || ex.InnerException is TimeoutException)
                {
                    (t as ICommunicationObject).Abort();
                }
                if (ex.InnerException != null)
                {
                    result = new ReturnMessage(ex.InnerException, methodCallMessage);
                }
                else
                {
                    result = new ReturnMessage(ex, methodCallMessage);
                }
            }
            return result;
        }
    }
}
